<?php

declare(strict_types=1);
namespace App\AdminApi\Module\System\Service;

use App\Common\Model\System\CrontabModel;
use Hyperf\Crontab\Annotation\Crontab as CrontabAnnotation;
use Hyperf\Di\Annotation\AnnotationCollector;
use Zms\Basics\BasicsServe;

class CrontabService extends BasicsServe
{

    private string $cacheKey = 'crontab:status';

    /**
     * @return CrontabModel::class
     */
    public static function model(): string
    {
        return CrontabModel::class;
    }

    /**
     * 获取定时任务注解和相关信息
     * @return array
     */
    public function getCrontabList(): array
    {
        $annotationList = AnnotationCollector::list();//全部注解
        $config = [];
        foreach (CrontabModel::get()->toArray() as $item) {
            $config[$item['sign']] = $item;
        }
        $list = [];
        $insert = [];
        foreach ($annotationList as $item) {
            if (!isset($item['_m'])) continue;
            foreach ($item['_m'] as $row) {
                foreach ($row as $info) {
                    if (!($info instanceof CrontabAnnotation && $info->enable === true)) {
                        continue;
                    }
                    $crontab = $info->toArray();
                    if (isset($config[$info->name])) {
                        $crontab['last_execution'] = $config[$info->name]['last_execution'];
                    } else {
                        $crontab['last_execution'] = 0;
                        $insert[] = ['sign' => $info->name, 'last_execution' => 0];
                    }
                    $list[] = $crontab;
                }
            }
        }
        CrontabModel::insert($insert);
        return $list;
    }


    /**
     * 记录任务日志
     * @param string $sign
     * @param bool|null $status
     * @return void
     */
    public function setCrontabLog(string $sign, ?bool $status): void
    {
        $time = time();

        $connection = $this->connection();

        //更新任务执行时间
        $connection->update("UPDATE `system_crontab` SET `last_execution`=? WHERE (`sign`=?)", [$time, $sign]);

        //添加任务执行记录
        $connection->insert("INSERT INTO `system_crontab_log` (`sign`, `time`, `status`) VALUES (?,?,?)", [$sign, $time, $status ? 1 : 0]);

        //只保留最新的200条记录
        $sql = "DELETE FROM `system_crontab_log` WHERE `id` IN (select `log`.`id` from (SELECT `id` from `system_crontab_log` where `sign` =? ORDER BY `id` DESC LIMIT 3000000 OFFSET 200) as `log`)";
        $connection->delete($sql, [$sign]);
    }
}